package edu.tsp.ga.mutators;

import edu.tsp.ga.Chromosome;
import edu.tsp.ga.utils.Pair;
import edu.tsp.ga.utils.RandomGenerator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class SimpleInversionMutator implements Mutator{

    @Override
    public Chromosome mutate(Chromosome chromosome) {
        Pair<Integer,Integer> pair = RandomGenerator.generateCrossPoints(chromosome.getGenes().size());
        return new Chromosome(simpleInversionMutate(chromosome.getGenes(), pair.head, pair.tail));
    }

    private <T> List<T> simpleInversionMutate(List<T> genes, int p1, int p2) {
        List<T> offspring = new ArrayList<>(genes);
        if(p1 < p2) {
            for(int i=p1, j=p2; i < j; i++,j--) {
                Collections.swap(offspring, i, j);
            }
        }else {
            int size = genes.size();
            for(int i=p1, j=p2; i != j; i++, j--) {
                i %= size;
                j = j < 0 ? size+j : j;
                if(i == j) break;
                if(i < j) {
                    return simpleInversionMutate(offspring, i, j);
                }
                Collections.swap(offspring, i, j);

            }
        }
        return offspring;
    }

    public static void main(String args[]) {
        SimpleInversionMutator mutator = new SimpleInversionMutator();
        List<Integer> i1 = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7,8));
        System.out.println(mutator.simpleInversionMutate(i1, 2, 4));
        System.out.println(mutator.simpleInversionMutate(i1, 6, 5));
        System.out.println(mutator.simpleInversionMutate(i1, 4, 0));
    }
}
